package com.zzh.lib.core.lang;

import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.view.View;

import com.zzh.lib.core.lang.span.TextShapeSpan;
import com.zzh.lib.core.utils.HResUtils;

import java.util.List;

/**
 * Created by ZZH on 2022/6/6.
 *
 * @Date: 2022/6/6
 * @Email: zzh_hz@126.com
 * @QQ: 1299234582
 * @Author: zzh
 * @Description: 字符串控制：例如控制文字大小，文字颜色，文字点击事件。
 * <p>
 * 要注意，应先设置点击事件，然后再设置其他样式。点击事件设置之后点击的文字默认是有下划线和变色
 * <p/>
 */
public class HStringSpannable extends SpannableStringBuilder {
    /**
     * 设置字体颜色
     *
     * @param text      文字
     * @param textColor 颜色
     * @return 当前实例
     */
    public HStringSpannable append(CharSequence text, int textColor) {
        ForegroundColorSpan textSpan = new ForegroundColorSpan(textColor);
        appendSpan(textSpan, text);
        return this;
    }

    /**
     * set the style constant defined in {@link Typeface}.
     *
     * @param text
     * @param style 字体：粗体，正常，斜体
     * @return
     */
    public HStringSpannable appendStyle(CharSequence text, int style) {
        StyleSpan textSpan = new StyleSpan(style);
        appendSpan(textSpan, text);
        return this;
    }


    /**
     * set the style constant defined in {@link Typeface}.
     *
     * @param text
     * @param style 字体：粗体，正常，斜体
     * @return
     */
    public HStringSpannable setStyle(CharSequence text, int style) {
        int[] position = HStrUtils.getStringFirstPosition(toString(), text.toString());
        if (position[0] < 0) {
            return this;
        }
        StyleSpan textSpan = new StyleSpan(style);
        setSpan(textSpan, position[0], position[1]);
        return this;
    }


    /**
     * 添加标签
     *
     * @param text        添加标签的文字
     * @param style       样式：STYLE_FILL = 0;//填充；STYLE_STROKE = 1;//扫边。扫边颜色默认和字体颜色一致
     * @param radius      圆角半径
     * @param bgColor     背景颜色
     * @param strokeColor 描边颜色
     * @param textColor   字体颜色
     * @return HStringSpannable
     */
    public HStringSpannable appendStrokeTag(String text, int radius, int strokeWidth, int margin, int bgColor, int strokeColor, int textColor) {
        if (!TextUtils.isEmpty(text)) {
            append(text);
            TextShapeSpan rs = new TextShapeSpan(bgColor, strokeColor, textColor, radius, TextShapeSpan.STYLE_STROKE);
            if (strokeWidth < 0) {
                strokeWidth = HResUtils.dp2px(1);
            }
            rs.setStrokeWidth(strokeWidth);
            rs.setMarginStart(margin);
            rs.setMarginEnd(margin);
            rs.setPaddingStart(2).setPaddingEnd(2);
            int[] position = HStrUtils.getStringFirstPosition(toString(), text);
            setSpan(rs, position[0], position[1], Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    public HStringSpannable appendFillTag(String text, int radius, int margin, int bgColor, int textColor) {
        if (!TextUtils.isEmpty(text)) {
            append(text);
            TextShapeSpan rs = new TextShapeSpan(bgColor, textColor, textColor, radius, TextShapeSpan.STYLE_FILL);
            rs.setMarginStart(margin);
            rs.setMarginEnd(margin);
            rs.setPaddingStart(2).setPaddingEnd(2);
            int[] position = HStrUtils.getStringFirstPosition(toString(), text);
            setSpan(rs, position[0], position[1], Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    public HStringSpannable appendFillTag(String text, int radius, int margin, int bgColor, int textColor, int textSize) {
        if (!TextUtils.isEmpty(text)) {
            append(text);
            TextShapeSpan rs = new TextShapeSpan(bgColor, textColor, textColor, radius, TextShapeSpan.STYLE_FILL);
            rs.setMarginStart(margin);
            rs.setMarginEnd(margin);
            rs.setTextSize(textSize);
            rs.setPaddingStart(2).setPaddingEnd(2);
            int[] position = HStrUtils.getStringFirstPosition(toString(), text);
            setSpan(rs, position[0], position[1], Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    public HStringSpannable appendFillTag(String text, int textColor, int margin, Drawable drawable) {
        if (!TextUtils.isEmpty(text)) {
            append(text);
            TextShapeSpan rs = new TextShapeSpan();
            rs.setBackgroundDrawable(drawable).setTxtColor(textColor);
            rs.setMarginStart(margin);
            rs.setMarginEnd(margin);
            rs.setPaddingStart(2).setPaddingEnd(2);
            int[] position = HStrUtils.getStringFirstPosition(toString(), text);
            setSpan(rs, position[0], position[1], Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    public HStringSpannable appendFillTag(String text, int textColor, int margin, int drawable) {
        if (!TextUtils.isEmpty(text)) {
            append(text);
            int[] position = HStrUtils.getStringFirstPosition(toString(), text);
            TextShapeSpan rs = new TextShapeSpan();
            rs.setBackgroundResource(drawable).setTxtColor(textColor);
            rs.setMarginStart(margin);
            rs.setMarginEnd(margin);
            rs.setPaddingStart(2).setPaddingEnd(2);
            setSpan(rs, position[0], position[1], Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    public HStringSpannable appendFillTagTextSize(String text, int textColor, int textSize, int margin, int drawable) {
        if (!TextUtils.isEmpty(text)) {
            append(text);
            int[] position = HStrUtils.getStringFirstPosition(toString(), text);
            TextShapeSpan rs = new TextShapeSpan();
            rs.setBackgroundResource(drawable).setTxtColor(textColor);
            rs.setMarginStart(margin);
            rs.setMarginEnd(margin);
            rs.setTextSize(textSize);
            rs.setPaddingStart(2).setPaddingEnd(2);
            setSpan(rs, position[0], position[1], Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    public HStringSpannable appendFillTagTextSize(String text, int textColor, int textSize, int margin, Drawable drawable) {
        if (!TextUtils.isEmpty(text)) {
            append(text);
            int[] position = HStrUtils.getStringFirstPosition(toString(), text);
            TextShapeSpan rs = new TextShapeSpan();
            rs.setBackgroundDrawable(drawable)
                    .setTxtColor(textColor);
            rs.setMarginStart(margin);
            rs.setMarginEnd(margin);
            rs.setTextSize(textSize);
            rs.setPaddingStart(2).setPaddingEnd(2);
            setSpan(rs, position[0], position[1], Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    public HStringSpannable appendFillTagTextSize(String text, int textColor, int textSize, int margin, int padding, Drawable drawable) {
        if (!TextUtils.isEmpty(text)) {
            append(text);
            int[] position = HStrUtils.getStringFirstPosition(toString(), text);
            TextShapeSpan rs = new TextShapeSpan();
            rs.setBackgroundDrawable(drawable)
                    .setTxtColor(textColor);
            rs.setMarginStart(margin);
            rs.setMarginEnd(margin);
            rs.setTextSize(textSize);
            rs.setPaddingStart(padding).setPaddingEnd(padding);
            setSpan(rs, position[0], position[1], Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    /**
     * 设置样式
     *
     * @param text          文字
     * @param listener      点击文字监听
     * @param textColor     文字颜色
     * @param textSize      文字大小
     * @param showUnderline 是否显示下划线
     * @return 当前实例
     */
    public HStringSpannable append(String text, View.OnClickListener listener, int textColor, int textSize, boolean showUnderline) {
        append(text);
        setStyle(text, listener, textColor, textSize, showUnderline);
        return this;
    }

    /**
     * 设置样式
     *
     * @param text          文字
     * @param listener      点击文字监听
     * @param textColor     文字颜色
     * @param textSize      文字大小
     * @param showUnderline 是否显示下划线
     * @return 当前实例
     */
    public HStringSpannable setStyle(String text, View.OnClickListener listener, int textColor, int textSize, boolean showUnderline) {
        int[] position = HStrUtils.getStringFirstPosition(toString(), text);
        if (position[0] != -1) {
            if (listener != null) {
                setSpan(new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        listener.onClick(widget);
                    }

                    @Override
                    public void updateDrawState(TextPaint ds) {
                        ds.setUnderlineText(showUnderline);
                        ds.setColor(textColor);
                    }
                }, position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
            }

            setSpan(new ForegroundColorSpan(textColor), position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
            setSpan(new AbsoluteSizeSpan(textSize), position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            append(text, listener, textColor, textSize, showUnderline);
        }
        return this;
    }

    /**
     * 设置点击事件
     *
     * @param text          点击事件的文字
     * @param listener      监听
     * @param textColor     点击事件的颜色。
     * @param showUnderline 是否显示下划线
     * @return 当前实例
     */
    public HStringSpannable setClick(String text, View.OnClickListener listener, int textColor, boolean showUnderline) {
        int[] position = HStrUtils.getStringFirstPosition(toString(), text);
        if (position[0] != -1) {
            if (listener != null) {
                setSpan(new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        listener.onClick(widget);
                    }

                    @Override
                    public void updateDrawState(TextPaint ds) {
                        ds.setColor(ds.linkColor);
                        ds.setUnderlineText(showUnderline);
                    }
                }, position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
                setSpan(new ForegroundColorSpan(textColor), position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        return this;
    }

    /**
     * 设置点击事件
     *
     * @param text          点击事件的文字
     * @param listener      监听
     * @param textColor     点击事件的颜色。
     * @param showUnderline 是否显示下划线
     */
    public void setAllClickable(String text, View.OnClickListener listener, int textColor, boolean showUnderline) {
        List<int[]> allPosition = HStrUtils.getStringAllPosition(toString(), text);
        if (!allPosition.isEmpty()) {
            for (int[] position : allPosition) {
                setSpan(new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        if (listener != null) {
                            listener.onClick(widget);
                        }
                    }

                    @Override
                    public void updateDrawState(TextPaint ds) {
                        ds.setColor(ds.linkColor);
                        ds.setUnderlineText(showUnderline);
                    }
                }, position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
                setSpan(new ForegroundColorSpan(textColor), position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
            }


        }
    }

    /**
     * 设置文字大小
     *
     * @param text     要设置的文字
     * @param textSize 文字大小
     * @return 当前对象
     */
    public HStringSpannable appendTextSize(CharSequence text, int textSize) {
        AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan(textSize);
        appendSpan(sizeSpan, text, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return this;
    }

    /**
     * 设置文字大小
     *
     * @param text     要设置的文字
     * @param textSize 文字大小
     * @return 当前对象
     */
    public HStringSpannable appendTextColorSize(String text, int textColor, int textSize) {
        append(text);
        int[] position = HStrUtils.getStringFirstPosition(toString(), text);
        setSpan(new ForegroundColorSpan(textColor), position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
        setSpan(new AbsoluteSizeSpan(textSize), position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
        return this;
    }

    public static final int DEFAULT_FLAG = SPAN_EXCLUSIVE_EXCLUSIVE;

    public HStringSpannable() {
    }

    public HStringSpannable(CharSequence text) {
        super(text);
    }

    public void appendSpan(Object span, CharSequence key) {
        this.appendSpan(span, key, DEFAULT_FLAG);
    }

    public void appendSpan(Object span, CharSequence key, int flags) {
        if (span != null && !TextUtils.isEmpty(key)) {
            this.append(key);
            int end = this.length();
            int start = end - key.length();
            this.setSpan(span, start, end, flags);
        }

    }

    public void addSpan(Object spanOld, Object spanNew) {
        this.addSpan(spanOld, spanNew, DEFAULT_FLAG);
    }

    public void addSpan(Object spanOld, Object spanNew, int flags) {
        if (spanNew != null && spanOld != null) {
            int end = this.getSpanEnd(spanOld);
            int start = this.getSpanStart(spanOld);
            this.setSpan(spanNew, start, end, flags);
        }

    }


    public void setSpan(Object what, int start, int end) {
        this.setSpan(what, start, end, DEFAULT_FLAG);
    }

    /**
     * 直接设置文字大小。如果此文字已经存在字符串中，否则添加
     *
     * @param text     改变文字样式
     * @param textSize 文字大小
     * @return 当前实例
     */
    public HStringSpannable setTextSize(String text, int textSize) {
        int[] position = HStrUtils.getStringFirstPosition(toString(), text);
        if (position[0] != -1) {
            AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan(textSize);
            appendSpan(sizeSpan, text, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

        return this;
    }

    /**
     * 直接设置文字大小。如果此文字已经存在字符串中，否则添加
     *
     * @param text     改变文字样式
     * @param textSize 文字大小
     * @return 当前实例
     */
    public HStringSpannable setAllTextSize(String text, int textSize) {
        List<int[]> allPosition = HStrUtils.getStringAllPosition(toString(), text);
        for (int[] position : allPosition) {
            if (position[0] != -1) {
                AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan(textSize);
                setSpan(sizeSpan, position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        return this;
    }

    /**
     * 直接设置文字颜色。如果此文字已经存在字符串中，否则添加
     *
     * @param text      改变文字样式
     * @param textColor 颜色
     * @return 当前实例
     */
    public HStringSpannable setTextColor(String text, int textColor) {
        int[] position = HStrUtils.getStringFirstPosition(toString(), text);
        if (position[0] != -1) {
            setSpan(new ForegroundColorSpan(textColor), position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return this;
    }

    /**
     * 直接设置文字颜色。如果此文字已经存在字符串中，否则添加
     *
     * @param text      改变文字样式
     * @param textColor 颜色
     * @return 当前实例
     */
    public HStringSpannable setAllTextColor(String text, int textColor) {
        List<int[]> allPosition = HStrUtils.getStringAllPosition(toString(), text);
        for (int[] position : allPosition) {
            if (position[0] != -1) {
                setSpan(new ForegroundColorSpan(textColor), position[0], position[1], SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        return this;
    }
}
